package com.ueboot.weishop.api.controller.activity;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.ueboot.core.exception.BusinessException;
import com.ueboot.core.http.response.Response;
import com.ueboot.core.utils.DateUtils;
import com.ueboot.weishop.api.SessionUtils;
import com.ueboot.weishop.api.controller.activity.vo.ActivityResp;
import com.ueboot.weishop.api.controller.activity.vo.SecKillActivityResp;
import com.ueboot.weishop.api.controller.activity.vo.VinCouponActivityResp;
import com.ueboot.weishop.entity.activity.ActivityAttrEntity;
import com.ueboot.weishop.entity.activity.ActivityEntity;
import com.ueboot.weishop.entity.goods.GoodsInfoEntity;
import com.ueboot.weishop.entity.user.CusGroup;
import com.ueboot.weishop.entity.user.FordClubMember;
import com.ueboot.weishop.entity.user.JoUser;
import com.ueboot.weishop.service.activity.ActivityAttrService;
import com.ueboot.weishop.service.activity.ActivityService;
import com.ueboot.weishop.service.cache.CacheService;
import com.ueboot.weishop.service.goods.GoodsInfoService;
import com.ueboot.weishop.service.user.CusGroupService;
import com.ueboot.weishop.service.user.FordClubMemberService;
import com.ueboot.weishop.service.user.JoUserService;
import com.ueboot.weishop.service.user.OilVinService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@RestController
@RequestMapping(value = "/api/public/activity")
public class ActivityController {

    @Autowired
    private ActivityService activityService;


    @Autowired
    private ActivityAttrService activityAttrService;

    @Autowired
    private GoodsInfoService goodsInfoService;

    @Autowired
    private CacheService cacheService;


    @Autowired
    private JoUserService joUserService;

    @Autowired
    private FordClubMemberService fordClubMemberService;

    @Autowired
    private OilVinService oilVinService;

    @Autowired
    private CusGroupService cusGroupService;

    @RequestMapping(value = "/coupon/activity/size", method = RequestMethod.GET)
    public Response<Integer> couponActivityGet() {

        String date = DateUtils.format(new Date(), DateUtils.FORMAT_DATE_DEFAULT);
        List<ActivityEntity> activityList = activityService.findByTypeAndDate(ActivityEntity.TYPE_COUPON, date);

        int size = 0;
        Date now = new Date();
        for (ActivityEntity entity : activityList) {
            if (now.before(entity.getStartTime()) || now.after(entity.getEndTime())) {
                continue;
            }
            size++;
        }

        return new Response<>(size);
    }

    @RequestMapping(value = "/coupon/get", method = RequestMethod.GET)
    public Response<List<VinCouponActivityResp>> couponGet() {

        String openId = SessionUtils.getOpenId();
        if (StringUtils.isEmpty(openId)) {
            throw new BusinessException("请使用微信！");
        }

        JoUser joUser = joUserService.findByWechatUserName(openId);
        List<FordClubMember> memberList = fordClubMemberService.findByOpenId(openId);


        //返回列表
        List<VinCouponActivityResp> body = new ArrayList<>();

        String date = DateUtils.format(new Date(), DateUtils.FORMAT_DATE_DEFAULT);
        List<ActivityEntity> activityList = activityService.findByTypeAndDate(ActivityEntity.TYPE_COUPON, date);

        if (activityList.isEmpty()) {
            throw new BusinessException("不在活动期间！");
        }
        if (joUser == null || memberList == null || memberList.size() == 0) {
            //未认证用户,返回代金券活动列表（不含VIN信息）
            log.info("openId:{},未认证用户登录!", openId);
            throw new BusinessException("未认证");
        }
        //已认证用户
        log.info("openId:{},认证用户登录!", openId);
        Date now = new Date();
        for (FordClubMember clubMember : memberList) {
            //获取VIN的用户类型
            CusGroup cusGroup = cusGroupService.findByVin(clubMember.getVvin());
            String type = cusGroup == null ? "C" : cusGroup.getGroupName();
            //判断用户是不是属于半合成机油用户
            boolean oilVin = oilVinService.findByVin(clubMember.getVvin()) != null;
            for (ActivityEntity entity : activityList) {
                if (now.before(entity.getStartTime()) || now.after(entity.getEndTime())) {
                    //该活动已经结束或未开始
                    continue;
                }

                //获取活动属性
                ActivityAttrEntity couponAmountAttr = null;
                ActivityAttrEntity couponProjectCodeAttr = null;
                ActivityAttrEntity couponActualCountAttr = null;
                ActivityAttrEntity couponCustomerTypeAttr = null;
                ActivityAttrEntity couponStartDateAttr = null;
                ActivityAttrEntity couponEndDateAttr = null;

                List<ActivityAttrEntity> activityAttrs = activityAttrService.findBySn(entity.getSn());

                for (ActivityAttrEntity attrEntity : activityAttrs) {
                    if ("couponAmount".equals(attrEntity.getKeyName())) {
                        couponAmountAttr = attrEntity;
                        continue;
                    }
                    if ("couponProjectCode".equals(attrEntity.getKeyName())) {
                        couponProjectCodeAttr = attrEntity;
                        continue;
                    }
                    if ("couponActualCount".equals(attrEntity.getKeyName())) {
                        couponActualCountAttr = attrEntity;
                        continue;
                    }
                    if ("couponCustomerType".equals(attrEntity.getKeyName())) {
                        couponCustomerTypeAttr = attrEntity;
                        continue;
                    }
                    if ("couponStartDate".equals(attrEntity.getKeyName())) {
                        couponStartDateAttr = attrEntity;
                        continue;
                    }
                    if ("couponEndDate".equals(attrEntity.getKeyName())) {
                        couponEndDateAttr = attrEntity;
                        continue;
                    }
                }
                //分析每个vin是否具有抽奖资格
                //A、B、C类
                if (couponCustomerTypeAttr == null) {
                    continue;
                }

                String countKey = "weishop:coupon:" + entity.getGroupCode() + "|" + couponCustomerTypeAttr.getValue();
                String countVinKey = countKey + clubMember.getVvin();
                Integer vinBuyCount = cacheService.getAlreadyBuyCount(entity.getSn(), countVinKey);

                boolean obtained = vinBuyCount == null || entity.getLimitCopies().intValue() > vinBuyCount.intValue();

                if (couponCustomerTypeAttr.getValue().equals(ActivityAttrEntity.CUSTOMER_TYPE_OIL)) {
                    if (oilVin) {
                        //不能领取该券
                        continue;
                    }
                    //属于半合成机油转合成机油用户
                    VinCouponActivityResp resp = this.copy(entity, couponProjectCodeAttr, couponCustomerTypeAttr, couponAmountAttr, couponActualCountAttr, couponStartDateAttr, couponEndDateAttr);

                    //判断是否领取
                    resp.setObtained(obtained);
                    resp.setVin(clubMember.getVvin());

                    body.add(resp);
                } else if (couponCustomerTypeAttr.getValue().equals(type)) {
                    VinCouponActivityResp resp = this.copy(entity, couponProjectCodeAttr, couponCustomerTypeAttr, couponAmountAttr, couponActualCountAttr, couponStartDateAttr, couponEndDateAttr);

                    //判断是否领取
                    resp.setObtained(obtained);
                    resp.setVin(clubMember.getVvin());

                    body.add(resp);
                }
            }
        }

        return new Response<>(body);
    }


    @RequestMapping(value = "/secKill/get", method = RequestMethod.POST)
    public Response<SecKillActivityResp> secKillGet() {
        List<ActivityEntity> activityList = activityService.findByTypeOrderByStartTimeAsc(ActivityEntity.TYPE_SEC_KILL);
        return this.find(activityList);
    }

    @RequestMapping(value = "/crowd", method = RequestMethod.POST)
    public Response<List<SecKillActivityResp>> crowdGet() {
        List<ActivityEntity> activityList = activityService.findByTypeOrderByStartTimeAsc(ActivityEntity.TYPE_CROW);
        List<SecKillActivityResp> activityRespList = Lists.newLinkedList();
        activityList.forEach(activity -> {
            List<String> goodsInfoList = goodsInfoService.findJSONByActivityId(activity.getId());
            GoodsInfoEntity goodsInfo = JSON.parseObject(goodsInfoList.get(0), GoodsInfoEntity.class);
            SecKillActivityResp resp = new SecKillActivityResp();
            BeanUtils.copyProperties(activity, resp);
            resp.setShortDesc(goodsInfo.getShortDesc());
            resp.setMainImgUrl(goodsInfo.getMainImgUrl());
            activityRespList.add(resp);
        });
        return new Response<>(activityRespList);
    }

    @RequestMapping(value = "/crowd/get/{id}", method = RequestMethod.POST)
    public Response<SecKillActivityResp> crowdGet(@PathVariable Long id) {
        ActivityEntity activity = activityService.get(id);
        if (activity == null) {//整个活动都数据
            throw new BusinessException("活动已结束！");
        }
        List<String> goodsInfoList = goodsInfoService.findJSONByActivityId(id);
        GoodsInfoEntity goodsInfo = JSON.parseObject(goodsInfoList.get(0), GoodsInfoEntity.class);
        SecKillActivityResp resp = new SecKillActivityResp();
        BeanUtils.copyProperties(activity, resp);
        resp.setId(activity.getId());
        resp.setSn(activity.getSn());
        resp.setStartTimeStr(DateUtils.format(activity.getStartTime(), DateUtils.FORMAT_DATE_TIME_HHMM));
        resp.setGoodsId(goodsInfo.getId());
        resp.setMainImgUrl(goodsInfo.getMainImgUrl());
        resp.setRemark(goodsInfo.getDetailDesc());
        String actCountCacheKey = activity.getSn() + ":" + activity.getId();
        Integer actualCount = cacheService.getAlreadyBuyCount(actCountCacheKey, activity.getPeriodNum());
        Long rollbackOrder = cacheService.countRollbackOrder(actCountCacheKey+":"+activity.getPeriodNum());
        log.info("回滚库存:{},actualCount:{}",rollbackOrder,actualCount);
        //需要减去回滚库存，才是真实已经购买的库存
        if (rollbackOrder != null && actualCount != null) {
            actualCount = actualCount - rollbackOrder.intValue();
        }
        log.info("actualCount:{},resp:{},activity:{}", actualCount, resp, activity);
        Double percent = 0D;
        if (actualCount != null && actualCount != 0) {
            if (ActivityEntity.TYPE_CROW.equals(activity.getType())) {
                percent = Math.floor((Float.valueOf(actualCount) / Float.valueOf(activity.getCrowdUnit())) * 100);
                if (actualCount > activity.getCrowdUnit()) {
                    percent = 100D;
                    log.info("已经满100%");
                }
            } else if (ActivityEntity.TYPE_SEC_KILL.equals(activity.getType())) {
                percent = Math.floor((Float.valueOf(actualCount) / Float.valueOf(activity.getSeckillProvideCopies())) * 100);
                if (actualCount > activity.getSeckillProvideCopies()) {
                    percent = 100D;
                    log.info("已经满100%");
                }
            }
        } else {
            actualCount = 0;
        }
        resp.setPercent(percent.intValue());
        resp.setCrowActualCount(actualCount);
        if (ActivityEntity.TYPE_CROW.equals(activity.getType())) {
            resp.setCrowActualCount(activity.getCrowdUnit() - actualCount);
            if (actualCount > activity.getCrowdUnit()) {
                resp.setCrowActualCount(activity.getCrowdUnit());
            }
        } else if (ActivityEntity.TYPE_SEC_KILL.equals(activity.getType())) {
            if (actualCount > activity.getSeckillProvideCopies()) {
                resp.setCrowActualCount(activity.getSeckillProvideCopies());
            }
        }
        return new Response<>(resp);
    }

    private VinCouponActivityResp copy(ActivityEntity entity, ActivityAttrEntity couponProjectCodeAttr, ActivityAttrEntity couponCustomerTypeAttr, ActivityAttrEntity couponAmountAttr, ActivityAttrEntity couponActualCountAttr, ActivityAttrEntity couponStartDateAttr, ActivityAttrEntity couponEndDateAttr) {
        VinCouponActivityResp resp = new VinCouponActivityResp();
        BeanUtils.copyProperties(entity, resp);
        resp.setActivityId(entity.getId());
        resp.setCouponAmount(couponAmountAttr == null || couponAmountAttr.getValue() == null ? 0 : Integer.parseInt(couponAmountAttr.getValue()) / 100);
        resp.setCouponProjectCode(couponProjectCodeAttr == null ? null : couponProjectCodeAttr.getValue());
        resp.setCouponActualCount(couponActualCountAttr == null || couponActualCountAttr.getValue() == null ? 0 : Integer.parseInt(couponActualCountAttr.getValue()));
        resp.setCouponStartDate(couponStartDateAttr == null ? null : couponStartDateAttr.getValue());
        resp.setCouponEndDate(couponEndDateAttr == null ? null : couponEndDateAttr.getValue());

        int totalCount = couponActualCountAttr == null || couponActualCountAttr.getValue() == null ? 0 : Integer.parseInt(couponActualCountAttr.getValue());

        String countKey = entity.getGroupCode() + "|" + couponCustomerTypeAttr.getValue();
        Integer buyCount = cacheService.getAlreadyBuyCount(entity.getSn(), countKey);


        //获取剩余数量
        resp.setSurplusCount(totalCount - (buyCount == null ? 0 : buyCount.intValue()));

        return resp;
    }


    private Response<SecKillActivityResp> find(List<ActivityEntity> activityList) {
        ActivityResp activityRespIng = null;// 正在进行中的活动信息
        ActivityResp activityRespNext = null;// 未找到正在进行中的活动，获取即将开始的活动信息
        Date now = new Date();
        for (ActivityEntity activity : activityList) {
            Date startTime = activity.getStartTime();
            Date endTime = activity.getEndTime();
            log.info("now.after{},now.before:{}", now.after(startTime), now.before(endTime));
            if (now.after(startTime) && now.before(endTime)) {
                activityRespIng = new ActivityResp();
                activityRespIng.setId(activity.getId());
                activityRespIng.setSn(activity.getSn());
                activityRespIng.setIng(Boolean.TRUE);
            } else if (activityRespNext == null && now.before(startTime)) {//下一期活动信息
                log.info("找到下一期:{},{}", startTime, endTime);
                activityRespNext = new ActivityResp();
                activityRespNext.setId(activity.getId());
                activityRespNext.setSn(activity.getSn());
                activityRespNext.setIng(Boolean.FALSE);
                activityRespNext.setStartTime(startTime);
            }
        }

        log.info("找到当期数据:activityRespIng:{},activityRespNext:{}", activityRespIng, activityRespNext);
        if (activityRespIng == null && activityRespNext == null) {//整个活动都数据
            throw new BusinessException("活动已结束！");
        }
        //活动开始第一次
        if (activityRespIng == null) {
            log.info("activityRespIng is null");
            ActivityEntity activityEntity = this.activityService.get(activityRespNext.getId());
            SecKillActivityResp resp = this.next(activityRespNext);
            resp.setName(activityEntity.getName());
            return new Response<>(resp);
        }
        ActivityEntity activityEntity = this.activityService.get(activityRespIng.getId());
        List<String> goodsInfoList = goodsInfoService.findJSONByActivityId(activityEntity.getId());
        if (goodsInfoList.size() < 1) {
            throw new BusinessException("活动产品获取异常，活动产品不存在");
        }
        GoodsInfoEntity goodsInfo = JSON.parseObject(goodsInfoList.get(0), GoodsInfoEntity.class);
        SecKillActivityResp resp = new SecKillActivityResp();
        BeanUtils.copyProperties(activityEntity, resp);
        resp.setId(activityRespIng.getId());
        resp.setSn(activityRespIng.getSn());
        resp.setIng(activityRespIng.getIng());
        resp.setStartTimeStr(DateUtils.format(activityEntity.getStartTime(), DateUtils.FORMAT_DATE_TIME_HHMM));
        resp.setSeckillPrice(activityEntity.getSeckillPrice() / 100);
        resp.setGoodsId(goodsInfo.getId());
        resp.setMainImgUrl(goodsInfo.getMainImgUrl());
        Integer actualCount = cacheService.getAlreadyBuyCount(activityEntity.getId() + "", goodsInfo.getId().toString());
        Long rollbackOrder = cacheService.countRollbackOrder(activityEntity.getId() + "");
        //需要减去回滚库存，才是真实已经购买的库存
        if (rollbackOrder != null && actualCount != null) {
            actualCount = actualCount - rollbackOrder.intValue();
        }
        log.info("actualCount:{},resp:{},activity:{}", actualCount, resp, activityEntity);
        Integer percent = 0;
        if (actualCount != null && actualCount != 0) {
            percent = Math.round((actualCount / resp.getSeckillProvideCopies()) * 100);
            if (actualCount > activityEntity.getSeckillProvideCopies()) {
                log.info("已经满100%");
                percent = 100;
            }
        } else {
            actualCount = 0;
        }
        if (percent == 100 && activityRespNext != null) {
            resp = this.next(activityRespNext);
            resp.setName(activityEntity.getName());
            return new Response<>(resp);
        }
        resp.setPercent(percent);
        resp.setCrowActualCount(actualCount);
        if (actualCount > activityEntity.getSeckillProvideCopies()) {
            resp.setCrowActualCount(activityEntity.getSeckillProvideCopies());
        }
        return new Response<>(resp);
    }

    private SecKillActivityResp next(ActivityResp activityRespNext) {
        SecKillActivityResp resp = new SecKillActivityResp();
        resp.setIng(Boolean.FALSE);
        resp.setStartTimeStr(DateUtils.format(activityRespNext.getStartTime(), DateUtils.FORMAT_DATE_TIME_HHMM));
        resp.setPercent(0);
        resp.setCrowActualCount(0);
        return resp;
    }

    public static void main(String[] args) {
        Double percent = Math.floor((Float.valueOf(299) / Float.valueOf(300)) * 100);
        System.out.println(percent.intValue());
    }
}
